Fix migration for SMP guests with 1 vcpu.
authorcl349@firebug.cl.cam.ac.uk <cl349@firebug.cl.cam.ac.uk>
Tue, 2 Aug 2005 23:13:13 +0000 (23:13 +0000)
committercl349@firebug.cl.cam.ac.uk <cl349@firebug.cl.cam.ac.uk>
Tue, 2 Aug 2005 23:13:13 +0000 (23:13 +0000)
Free/setup timer irq on suspend/restore.
Only tested to localhost.  Also add initial code for >1 vcpu guests.
Signed-off-by: Christian Limpach <Christian.Limpach@cl.cam.ac.uk>
linux-2.6-xen-sparse/arch/xen/i386/kernel/smpboot.c
linux-2.6-xen-sparse/arch/xen/i386/kernel/time.c

index f8ef335b6bc2e1024d0ddbcde3b4611085afc220..87d0d07343f531a8541ef189977a3b4801557718 100644 (file)
@@ -1560,10 +1560,14 @@ static void smp_intr_exit(void)
 
 void smp_suspend(void)
 {
+       /* XXX todo: take down time and ipi's on all cpus */
+       local_teardown_timer_irq();
        smp_intr_exit();
 }
 
 void smp_resume(void)
 {
+       /* XXX todo: restore time and ipi's on all cpus */
        smp_intr_init();
+       local_setup_timer_irq();
 }
index 56f6316cc47a47459b2e82291c61659a4e4a8e71..f64d6d1d26fbde90518b02f505114c6d6ac9408c 100644 (file)
@@ -860,6 +860,8 @@ void start_hz_timer(void)
 void time_suspend(void)
 {
        /* nothing */
+       teardown_irq(per_cpu(timer_irq, 0), &irq_timer);
+       unbind_virq_from_irq(VIRQ_TIMER);
 }
 
 /* No locking required. We are only CPU running, and interrupts are off. */
@@ -874,10 +876,25 @@ void time_resume(void)
        processed_system_time =
                per_cpu(shadow_time, smp_processor_id()).system_timestamp;
        per_cpu(processed_system_time, 0) = processed_system_time;
+
+       per_cpu(timer_irq, 0) = bind_virq_to_irq(VIRQ_TIMER);
+       (void)setup_irq(per_cpu(timer_irq, 0), &irq_timer);
 }
 
 #ifdef CONFIG_SMP
 static char timer_name[NR_CPUS][15];
+void local_setup_timer_irq(void)
+{
+       int cpu = smp_processor_id();
+
+       if (cpu == 0)
+               return;
+       per_cpu(timer_irq, cpu) = bind_virq_to_irq(VIRQ_TIMER);
+       sprintf(timer_name[cpu], "timer%d", cpu);
+       BUG_ON(request_irq(per_cpu(timer_irq, cpu), timer_interrupt,
+                          SA_INTERRUPT, timer_name[cpu], NULL));
+}
+
 void local_setup_timer(void)
 {
        int seq, cpu = smp_processor_id();
@@ -888,10 +905,17 @@ void local_setup_timer(void)
                        per_cpu(shadow_time, cpu).system_timestamp;
        } while (read_seqretry(&xtime_lock, seq));
 
-       per_cpu(timer_irq, cpu) = bind_virq_to_irq(VIRQ_TIMER);
-       sprintf(timer_name[cpu], "timer%d", cpu);
-       BUG_ON(request_irq(per_cpu(timer_irq, cpu), timer_interrupt,
-                          SA_INTERRUPT, timer_name[cpu], NULL));
+       local_setup_timer_irq();
+}
+
+void local_teardown_timer_irq(void)
+{
+       int cpu = smp_processor_id();
+
+       if (cpu == 0)
+               return;
+       free_irq(per_cpu(timer_irq, cpu), NULL);
+       unbind_virq_from_irq(VIRQ_TIMER);
 }
 #endif